延續昨天,我們來看可以怎麼在 Laravel 框架下實作簽證的驗證。
有點像 pipe 可以一個串一個去處理請求。例如,我們可以讓請求都先做 authentication 通過後才做進一步處理。當然我們也可以自定義一些客製化的流程,例如 verify signature。
以下就以驗證簽章為例來實作 Laravel middleware
$ php artisan make:middleware VerifySignature
class VerifySignature
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
// 對方的 signature 放在 header
$signature = $request->headers->get('X-Signature');
$body = $request->getContent();
if ($signature !== hash_hmac('sha256', $body, config('klk.secret'))) {
// 如果驗證失敗簡單回覆個訊息
$body = [
"code" => 401,
"message" => "signature error",
"timestamp" => date('Y-m-d H:i:s')
];
return response(json_encode($body), 401)->header('Content-Type', 'application/json');
}
return $next($request);
}
}
// 編輯 App\Http\Kernel
/**
* The application's route middleware.
*
* These middleware may be assigned to groups or used individually.
*
* @var array
*/
protected $routeMiddleware = [
// 新增我們的 middleware,key 看要取什麼名字都可以
'verify.signature' => \App\Http\Middleware\VerifySignature::class
];
可以直接這樣使用
Route::middleware('verify.signature')->post('webhook/handler', 'WebhooksController@handle');
也可以用 group,因為可能多支 webhook 都要通過同樣的簽章驗證
Route::middleware('verify.signature')->group(function () {
// Route::post();
// Route::post();
// Route::post();
// ...
});
注意!上面 routes 寫法是 Laravel 7,最新的寫法請參閱官方文件